package com.szholly.plug.activity.deployer;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

import com.szholly.utils.common.web.IRealPathResolver;

/**
 * 定义工作流自动部署类
 */
public class WorkflowDeployer implements InitializingBean,
		ApplicationContextAware {

	private static Logger logger = Logger.getLogger(WorkflowDeployer.class);
	
	@Autowired
	private IRealPathResolver realPathResolver;

	private String deploymentPath;
	private ApplicationContext appCtx;

	public void setDeploymentPath(String resources) {
		this.deploymentPath = resources;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.appCtx = applicationContext;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		String basePath = realPathResolver.get("/") + deploymentPath;
		List<String> fileList = new ArrayList<String>();
		getName(basePath, fileList);
		// 向下查询两级目录
		List<Resource> deploymentResources = new ArrayList<Resource>();
		for(String file : fileList){
			Resource fileRource = new FileSystemResource(file);
			deploymentResources.add(fileRource);
		}

		if (deploymentResources != null) {
			RepositoryService repositoryService = appCtx.getBean(RepositoryService.class);
			for (Resource r : deploymentResources) {
				String deploymentName = r.getFilename();
				String resourceName = r.getFilename();
				boolean doDeploy = true;
				try{
					List<Deployment> deployments = repositoryService
							.createDeploymentQuery().deploymentName(deploymentName)
							.orderByDeploymenTime().desc().list();
					if (!deployments.isEmpty()) {
						Deployment existing = deployments.get(0);
						InputStream in = repositoryService.getResourceAsStream(
								existing.getId(), resourceName);
						if (in != null) {
							File f = File.createTempFile("deployment", "xml",
									new File(System.getProperty("java.io.tmpdir")));
							f.deleteOnExit();
							OutputStream out = new FileOutputStream(f);
							IOUtils.copy(in, out);
							in.close();
							out.close();
							doDeploy = (FileUtils.checksumCRC32(f) != FileUtils
									.checksumCRC32(r.getFile()));
						} else {
							logger.info("afterPropertiesSet 不能读取资源 " + resourceName + ", 输入流为空");
						}
					}
					if (doDeploy) {
						repositoryService.createDeployment().name(deploymentName)
								.addInputStream(resourceName, r.getInputStream())
								.deploy();
						logger.info("WorkflowDeployer afterPropertiesSet 文件部署成功 : " + r.getFilename());
					}
				}catch(Exception ex){
					logger.error("WorkflowDeployer afterPropertiesSet 文件【"+resourceName+"】部署失败，原因 : " + ex.getMessage());
				}
			}
		}
	}

	private static void getName(String path, List<String> fileList) {
		File file = new File(path);
		if (file.isDirectory()) {
			File[] dirFile = file.listFiles();
			for (File f : dirFile) {
				if (f.isDirectory())
					getName(f.getAbsolutePath(), fileList);
				else {
					if (f.getName().endsWith(".bpmn")){
						fileList.add(f.getAbsolutePath());
					}
				}
			}
		}else{
			if (file.getName().endsWith(".bpmn")){
				fileList.add(file.getAbsolutePath());
			}
		}
	}
}